home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '98 presents:
-
- Virtua Squad - CD crack by Static Vengeance
-
- Requirements:
- hex editor and full install
-
- Having already played (and cracked) Virtua Squad 2 (VS2), I thought I would look at Virtua Squad.
- The first game is a bit older and as such doesn't support Direct3D which is shame. However the game has
- different "cases" (locations) to play so I decided to crack this one too. And as long as I am going to go
- through the effort I thought I would pass along what I learned from this one. First the CD check routine
- is nearly the same as the one used in VS2, but I added a few other comments to Virtua Squad's routine. Okay,
- lets get started, you will need to use W32Dasm to follow along. Alright, first thing you need to do is to
- disassemble the exe file ppjdd.exe. Now when you run the game without the CD a dialog box comes up right
- away and asks for the CD, no network option like VS2. However, unlike VS2, there is a string ref you will
- find while in W32Dasm. Using the same old method, go up to the menu bar and select "Refs" and then select
- "String data references" from the drop down menu. Then from the Refs box, grab the slider bar and scroll down.
- You will find the following string refs to check out: "Please insert VIRTUA SQUAD CD." and like VS2 there is
- a ref to the executable file on the CD with volume (path) name for you to check out: "NATIVE\VCOP\PPJDD.EXE"
- So double click on the "Please insert..." ref and that will drop you right in the middle of the routine
- that checks for the CD. If you doulble click on the exe file's path you will be in the middle of the code
- that looks for the file on the CD, which is actual CD check. So let's begin with the section that asks
- the user to put the CD in the drive and see where things go from there:
-
- * Referenced by a CALL at Address:
- |:004094D6 <-- Where the called came from, we'll make use of this later
- |
- :0040AEA0 56 push esi
-
- * Reference To: USER32.MessageBoxA, Ord:0197h
- |
- :0040AEA1 8B3530C42D01 mov esi, dword ptr [012DC430]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AEDB(C)
- |
- :0040AEA7 E864FFFFFF call 0040AE10 <-- Actual CD check routine (see below)
-
- * Possible StringData Ref from Data Obj ->"VIRTUA SQUAD"
- |
- :0040AEAC 8B0D10674800 mov ecx, dword ptr [00486710]
- :0040AEB2 A3EC452D01 mov dword ptr [012D45EC], eax <-- Get the result of the CD check from here
- :0040AEB7 83F8FF cmp eax, FFFFFFFF <-- Compare against known fail value
- :0040AEBA A1202D2D01 mov eax, dword ptr [012D2D20]
- :0040AEBF 7520 jne 0040AEE1 <-- Take this jump if the CD check passed
- :0040AEC1 6A35 push 00000035 <-- Otherwise "fall" through and ask for
- :0040AEC3 85C0 test eax, eax <-- the user to put the CD in the drive.
- :0040AEC5 51 push ecx
- :0040AEC6 7407 je 0040AECF
-
- * Possible StringData Ref from Data Obj ->"VIRTUA SQUAD "
- |
- :0040AEC8 6890684800 push 00486890
- :0040AECD EB05 jmp 0040AED4
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AEC6(C)
- |
- * Possible StringData Ref from Data Obj ->"Please insert VIRTUA SQUAD CD." <-- String which lead us here
- |
- :0040AECF 6870684800 push 00486870
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AECD(U)
- |
- :0040AED4 6A00 push 00000000
- :0040AED6 FFD6 call esi <-- Do the pop up dialog box
- :0040AED8 83F802 cmp eax, 00000002 <-- 00000002 means you hit "cancel"
- :0040AEDB 75CA jne 0040AEA7 <-- Otherwise loop back up and check again
- :0040AEDD 33C0 xor eax, eax <-- A zero in eax means CD check failed
- :0040AEDF 5E pop esi
- :0040AEE0 C3 ret <-- Return to caller with result
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AEBF(C)
- |
- :0040AEE1 B801000000 mov eax, 00000001 <-- A one in eax means CD check passed!
- :0040AEE6 5E pop esi
- :0040AEE7 C3 ret <-- Return to caller
-
- That was the code that asks the user to put the CD in the drive if not found during the CD check.
- We now have enough information to crack this one. We know where the call to the above routine is made
- from and we know a successful call returns with 00000001 in eax. However, becuase this is a tutorial I'll
- also show you the routine that checks for the CD. That routine is at 40AE10 and looks alot like this:
-
- * Referenced by a CALL at Address:
- |:0040AEA7
- |
- :0040AE10 83EC50 sub esp, 00000050
- :0040AE13 53 push ebx
- :0040AE14 56 push esi
- :0040AE15 57 push edi
- :0040AE16 33DB xor ebx, ebx <-- Try/retry counter, zero it out
- :0040AE18 55 push ebp
-
- * Reference To: KERNEL32.GetLogicalDrives, Ord:00E7h <-- Good text string to search for is
- | <-- "GetLogicalDrives"
- :0040AE19 FF15E8C32D01 Call dword ptr [012DC3E8]
- :0040AE1F 8BE8 mov ebp, eax
-
- * Reference To: KERNEL32._lopen, Ord:0262h
- |
- :0040AE21 8B350CC42D01 mov esi, dword ptr [012DC40C]
-
- * Reference To: KERNEL32.GetDriveTypeA, Ord:00CEh <-- Another useful text string would be
- | <-- "GetDriveType"
- :0040AE27 8B3DD4C32D01 mov edi, dword ptr [012DC3D4]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AE7F(C)
- |
- :0040AE2D B801000000 mov eax, 00000001
- :0040AE32 8ACB mov cl, bl
- :0040AE34 D3E0 shl eax, cl
- :0040AE36 85C5 test ebp, eax
- :0040AE38 7441 je 0040AE7B
- :0040AE3A 8D4341 lea eax, dword ptr [ebx+41]
- :0040AE3D 8D4C2410 lea ecx, dword ptr [esp+10]
- :0040AE41 50 push eax
-
- * Possible StringData Ref from Data Obj ->"%c:\" <-- Commonly used Ref string in CD checks
- |
- :0040AE42 6868684800 push 00486868
- :0040AE47 51 push ecx
-
- * Reference To: USER32.wsprintfA, Ord:026Ch
- |
- :0040AE48 FF15A4C42D01 Call dword ptr [012DC4A4]
- :0040AE4E 8D4C241C lea ecx, dword ptr [esp+1C]
- :0040AE52 83C40C add esp, 0000000C
- :0040AE55 51 push ecx
- :0040AE56 FFD7 call edi
- :0040AE58 83F805 cmp eax, 00000005
- :0040AE5B 751E jne 0040AE7B
- :0040AE5D 8D442410 lea eax, dword ptr [esp+10]
-
- * Possible StringData Ref from Data Obj ->"NATIVE\VCOP\PPJDD.EXE" <-- File to check for with the CD path
- |
- :0040AE61 6850684800 push 00486850
- :0040AE66 50 push eax
-
- * Reference To: KERNEL32.lstrcatA, Ord:0266h
- |
- :0040AE67 FF15D0C32D01 Call dword ptr [012DC3D0]
- :0040AE6D 8D442410 lea eax, dword ptr [esp+10]
- :0040AE71 6A00 push 00000000
- :0040AE73 50 push eax
- :0040AE74 FFD6 call esi
- :0040AE76 83F8FF cmp eax, FFFFFFFF
- :0040AE79 7508 jne 0040AE83 <-- Take this jump if the file was read
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:0040AE38(C), :0040AE5B(C)
- |
- :0040AE7B 43 inc ebx <-- Made another check, add 1 to ebx
- :0040AE7C 83FB20 cmp ebx, 00000020 <-- Try up to 20h (32) times
- :0040AE7F 7CAC jl 0040AE2D <-- Keep trying to find the CD until you hit 32
- :0040AE81 EB07 jmp 0040AE8A <-- Tried 32 times and STILL didn't find it
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AE79(C)
- |
- :0040AE83 50 push eax
-
- * Reference To: KERNEL32._lclose, Ord:025Fh
- |
- :0040AE84 FF15CCC32D01 Call dword ptr [012DC3CC]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AE81(U)
- |
- :0040AE8A B8FFFFFFFF mov eax, FFFFFFFF <-- This is the fail value
- :0040AE8F 83FB20 cmp ebx, 00000020 <-- Did we fail to find the file 32 times?
- :0040AE92 7402 je 0040AE96 <-- If yes, take this jump CD check=fail
- :0040AE94 8BC3 mov eax, ebx <-- This is THE vital instruction for pass/fail
- <-- anything other than FFFFFFFF = pass
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0040AE92(C)
- |
- :0040AE96 5D pop ebp
- :0040AE97 5F pop edi
- :0040AE98 5E pop esi
- :0040AE99 5B pop ebx
- :0040AE9A 83C450 add esp, 00000050
- :0040AE9D C3 ret <-- Finally return to the caller
-
- While it's not completely important that you understand each and every instruction and or compare,
- you need to see (understand) the general "flow" of the code. You start off by getting the drive location
- (ie drive D, or whatever, is the CD rom), then check for the file on the CD. The one thing that you really
- need to pay attention to is the "return to caller" section of the routine. This is where the vital choise
- is made between pass or fail. Then back track (through the callers) and find a "good" spot to make your
- patch. One method of cracking Virtua Squad would be to change the je 0040AE96 (at 40AE94) to two NOP's.
- This would allow the code to fall through and set up for a "good" CD check (the mov eax, ebx). However,
- I have always believed, why actually go through the CD check routine if you don't HAVE to, right? That's
- why I back track up to a higher level to disable the routine. As such, let's take a look at the first
- section of code where it was called from 4094D6. We need to list the surounding code (at 4094D6) and see
- what we have.
-
- -- Program Code --
- :004094CD 8B44243C mov eax, dword ptr [esp+3C]
- :004094D1 A300152D01 mov dword ptr [012D1500], eax
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004094B2(C)
- |
- :004094D6 E8C5190000 call 0040AEA0 <-- Do the whole CD check routine
- :004094DB 85C0 test eax, eax <-- Test the value returned in eax
- :004094DD 750C jne 004094EB <-- Take this jump for a good CD check
- :004094DF 33C0 xor eax, eax <-- Otherwise set up to quit back to Win95
- :004094E1 5D pop ebp
- :004094E2 5F pop edi
- :004094E3 5E pop esi
- :004094E4 5B pop ebx
- :004094E5 83C420 add esp, 00000020
- :004094E8 C21000 ret 0010
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004094DD(C)
- |
- :004094EB 8B7C2440 mov edi, dword ptr [esp+40]
- :004094EF 57 push edi
- :004094F0 53 push ebx
- :004094F1 E87A020000 call 00409770
- :004094F6 83C408 add esp, 00000008
- -- Continuing Program Code --
-
- From here you can see the "only" thing you need to do is to change the call to the CD check to
- mov eax, 00000001. This will in turn force the jne 4094EB to always be taken. Which, of course, allows
- you to play Virtua Squad without having the CD in your CD Rom drive! Now you need to make the patch to
- file. There are two versions of the game on the CD that I had to look at. One for Direct Draw called
- ppjdd.exe and one that's a native NVida port called vcop.exe. Too bad there's not a D3D version or a
- native glide port for this game. Anyways, here are the edits for both files:
-
- Edit ppjdd.exe at offset 35,030
- ===============================
- Search for: E8 C5 19 00 00
- Chagne to : B8 01 00 00 00
-
- Edit vcop.exe at offset 266,968
- ===============================
- Search for: E8 B7 17 00 00
- Chagne to : B8 01 00 00 00
-
- Another game has been FiX'ed with a little help from your humble author... Until next time,
- practice on something and put out a tutorial for the rest of us to read. That way I'll know someone
- is reading (and learning from) these articles I put out.
-
- Static Vengeance
-